                                                                     
                                                                     
                                                                     
                                             
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
class ClientContext 
{

    String [ ]properties;
    String[ ]objectNames;
    String [ ]objectAccesses;
    String [ ][ ]association;    
	static int object_count=0;	
    static int property_count=0;
    static int access_count=0;
    BufferedWriter output;	
	public  int countProperties() throws IOException
   {
	  int count=0;
	    FileInputStream fstreamForProperties;
		try 
		{
			fstreamForProperties = new FileInputStream("InfoFiles/Properties.txt");
			DataInputStream inForProperties = new DataInputStream(fstreamForProperties);
			BufferedReader brProperties = new BufferedReader(new InputStreamReader(inForProperties));
			 while ((brProperties.readLine()) != null)   {
			      count++;
			 }
			inForProperties.close();
		} catch (FileNotFoundException e) {		
			
			e.printStackTrace();
		}   
		finally{
			
			
		}
	    
	  
	  return count;
  }
  public  int countObjects() throws IOException
  {
	  int count=0; 
	  FileInputStream fstreamForObjectStatement = new FileInputStream("InfoFiles/Objects.txt");   
	  DataInputStream inForObjectStmnt = new DataInputStream(fstreamForObjectStatement);
	  BufferedReader brObjectStmnt = new BufferedReader(new InputStreamReader(inForObjectStmnt));
	  
	    String ObjectStmnts = brObjectStmnt.readLine();
	    
	    while (  ObjectStmnts!=null )   {
	    	count++;
	    	ObjectStmnts = brObjectStmnt.readLine();
	    }
	        	  
	  
	  inForObjectStmnt.close();
	  
	  
	  return count;
  }
  public int objectAndAccessCount() throws Exception
  {
	  int count=0;
	  FileInputStream fstreamForObjectStatement = new FileInputStream("InfoFiles/ObjectAccesses.txt");   
	  DataInputStream inForObjectAccessesStmnt = new DataInputStream(fstreamForObjectStatement);
	  BufferedReader brAccessesObjects = new BufferedReader(new InputStreamReader(inForObjectAccessesStmnt));
	  String ObjectAccessesStmnts=null;
	  while ((ObjectAccessesStmnts=brAccessesObjects.readLine()) != null){		  
		 if(!ObjectAccessesStmnts.contentEquals("End of Object")){
			 count++;
		 }			 
	  }  
	  inForObjectAccessesStmnt.close();
	
	  return count;
  }
  public boolean objectAlreadyExits(String object){
	  for(int i=0; i<object_count; i++)
	  {		  
		 
		  if(objectNames[i].contentEquals(object)){
			  return true;
		  }
			  
	  }
	  
	  return false;
  }
  public boolean propertyAlreadyExits(String property){
	  for(int i=0; i<property_count; i++){
		  
		  if(properties[i].contentEquals(property)){
			  return true;
	  }
			  
	  }
	  
	  return false;
  }  
  public void extractInfo(String[] inputFileName, int num_files)
  {
		try{
			
	    ClientParser newParser=new ClientParser();
	 	newParser.parseClientClass(inputFileName, num_files);
	 		
	    		
		int propCount=countProperties();	
		int objectCount =countObjects();	
		access_count =objectAndAccessCount();
	
	    FileInputStream fstreamForProperties = new FileInputStream("InfoFiles/Properties.txt");   
	    DataInputStream inForProperties = new DataInputStream(fstreamForProperties);
	    BufferedReader brProperties = new BufferedReader(new InputStreamReader(inForProperties));
	    
	    FileInputStream fstreamForObject = new FileInputStream("InfoFiles/Objects.txt");   
	    DataInputStream inForObject = new DataInputStream(fstreamForObject);
	    BufferedReader brObjects = new BufferedReader(new InputStreamReader(inForObject));
	    
	    FileInputStream fstreamForObjectStatement = new FileInputStream("InfoFiles/ObjectAccesses.txt");   
	    DataInputStream inForObjectAccessesStmnt = new DataInputStream(fstreamForObjectStatement);
	    BufferedReader brAccessesObjects = new BufferedReader(new InputStreamReader(inForObjectAccessesStmnt));
	   
	    properties=new String[propCount];
	    objectNames= new String[objectCount];
	    objectAccesses=new String[access_count];
	    
	    String property=null;
	    String object=null;
	    String objectAccessesStmnts=null;	    
	    
	    while ((property=brProperties.readLine()) != null) {
	    	if(!propertyAlreadyExits(property))
		  	properties[property_count++]=property;
		}   
	   
	    while ((object=brObjects.readLine()) != null) {
	    	if(!objectAlreadyExits(object)){
	    		objectNames[object_count++]=object;
	    	}
		}   
	    int index=0;
	    while ((objectAccessesStmnts=brAccessesObjects.readLine()) != null) {
	    	if(!objectAccessesStmnts.contentEquals("End of Object")){	    		
	    		objectAccesses[index++]=objectAccessesStmnts;
	    	}
	    } 
	    	    
	    association=new String[object_count][property_count];
	    for(int k=0; k<object_count; k++){
	    	for(int y=0; y<property_count; y++){
	    		association[k][y]="0";
	    	}	    	    		
	    } 
	   
	    for(int t=0; t<object_count; t++)
		{
	        	    			
	    			for(int s=0; s<property_count; s++)
	    			{
	    				for(int iterAccss=0; iterAccss<access_count; iterAccss++)
	    				{
	    					if(objectNames[t].contentEquals(objectAccesses[iterAccss]))
	    					{
		    					if(objectAccesses[++iterAccss].contentEquals(properties[s])&&iterAccss<access_count){
		    						association[t][s]="1";    					
		    					}

	    					}
	    						
	    				}
	    			}    			
	    
	    }  
	    inForProperties.close();
	    inForObject.close();
	    inForObjectAccessesStmnt.close();
		}
		catch(Exception e){
			e.printStackTrace();
		}
}

  public void generateConExpInput(String [ ]inputFilesName, String outputFileName, int num_files)
  {
	
	   
	 	try{
	 	extractInfo(inputFilesName, num_files);	   		
	    output = new BufferedWriter(new FileWriter(outputFileName));
	    output.write(";");
	    
	    for(int iter=0; iter<property_count; iter++)
	    {    
	    	output.write(properties[iter]);	    
	    	output.write(";");
	    }
	    
	    output.newLine();
	    output.newLine();
	    for(int x=0; x<object_count; x++)
	    {
	    	output.write(objectNames[x]);
            output.write(";");
	    	for(int y=0; y<property_count; y++)
	    	{    		
	    		output.write(association[x][y]);    		
	    		output.write(";");
	    	}    	
	    	output.newLine();
	    }	   
	 
		output.close();
	    }catch (Exception e){
	    	
	      e.printStackTrace();
	      
	    }
	    
		
  }
    public void generateGaliciaInput(String []inputFilesName, String outputFileName, int num_files)
  {
	
	   
	 	try{
	   
	 	extractInfo(inputFilesName, num_files);				
        output = new BufferedWriter(new FileWriter(outputFileName));
	    output.write("[Relational Context]\rClientClass\r[Binary Relation]\rClientClass\r");
	    for(int x=0; x<object_count; x++)
	    {
	    	output.write(objectNames[x]);
	    	output.write(" | ");
	    }
	    output.write("\r");
	    
	    for(int iter=0; iter<property_count; iter++)
	    {    
	    	output.write(properties[iter]);	    
	    	output.write(" | ");
	    }
	    output.write("\r");
	    for(int x=0; x<object_count; x++)
	    {
	    	for(int y=0; y<property_count; y++)
	    	{    		
	    		output.write(association[x][y]);    		
	    		output.write(" ");
	    	}
	    	output.write("\r");
	    	
	    }	
	   
	 
		output.close();
	    }catch (Exception e){	    	
	      e.printStackTrace();
	      
	    }
	    
		
  }
 
}


